package com.kexin.coupon.controller;


import java.util.HashMap;
import java.util.Map;

import com.kexin.common.utils.JWTUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.kexin.common.exception.WebException;
import com.kexin.common.user.entity.UserBase;
import com.kexin.common.user.service.IUserBaseService;
import com.kexin.common.utils.PageData;
import com.kexin.common.utils.PDSignUtil;
import com.kexin.common.utils.Result;
import com.kexin.coupon.entity.CouponOrder;
import com.kexin.coupon.service.ICouponOrderService;
import com.kexin.coupon.vo.OrderDetail;
import com.kexin.coupon.vo.PlaceOrder;
import com.kexin.fpay.api.FPayApi;
import com.kexin.fpay.config.FPayConfig;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * 卡券订单
 *
 * @author ao
 * @since 2021-07-20
 */
@Api(tags = "卡券订单")
@RestController
@RequestMapping("/couponOrder")
public class CouponOrderController {

	Logger log = LoggerFactory.getLogger(CouponOrderController.class);

	@Autowired
	private JWTUtils jwtUtils;

	@Autowired
	private ICouponOrderService couponOrderService;

	@Autowired
	private IUserBaseService userBaseService;

	@ApiOperation("获取卡券订单列表接口")
    @ApiImplicitParams({
    	@ApiImplicitParam(name="couponName",value="卡券名称（模糊查询）",dataType="String",paramType="query"),
		@ApiImplicitParam(name="payState",value="支付状态，0未支付，1已支付，2已过期，3已核销（多个状态以“,”分割）",dataType="String",paramType="query"),
		@ApiImplicitParam(name="useState",value="使用状态，0未使用，1已使用（多个状态以“,”分割）",dataType="String",paramType="query"),
		@ApiImplicitParam(name="refundState",value="退款状态，0未退款，1已退款，2退款失败，3退款中（多个状态以“,”分割）",dataType="String",paramType="query"),
		@ApiImplicitParam(name="current",value="页码",dataType="int",paramType="query"),
		@ApiImplicitParam(name="size",value="单页显示条数",dataType="int",paramType="query")
	})
    @PostMapping("/list")
	public Result<PageData<CouponOrder>> list(String couponName, 
			String payState, String useState, String refundState, 
			Integer current, Integer size) {
		try {
			UserBase userBase = userBaseService.getCurrentUser();
			Integer userId = userBase.getId();
			return new Result<PageData<CouponOrder>>(new PageData<CouponOrder>(
					couponOrderService.queryList(userId, couponName, 
					payState, useState, refundState, current, size)));
		} catch (Exception e) {
			e.printStackTrace();
            throw new WebException("获取卡券订单列表出错", e);
		}
	}

	@ApiOperation("卡券下单接口")
    @ApiImplicitParams({
		@ApiImplicitParam(name="couponId",value="卡券id",dataType="int",paramType="query"),
		@ApiImplicitParam(name="num",value="购买数量（默认1）",dataType="int",paramType="query")
	})
    @PostMapping("/submitOrder")
	public Result<OrderDetail> submitOrder(Integer couponId, Integer num) {
		try {
			UserBase userBase = userBaseService.getCurrentUser();
			Integer userId = userBase.getId();
			return new Result<OrderDetail>(couponOrderService
					.submitOrder(userId, couponId, num));
		} catch (Exception e) {
			e.printStackTrace();
            throw new WebException(e.getMessage(), e);
		}
	}

	@ApiOperation("卡券订单支付接口")
    @ApiImplicitParams({
		@ApiImplicitParam(name="orderNo",value="订单号",dataType="String",paramType="query")
	})
    @PostMapping("/placeAnOrder")
	public Result<PlaceOrder> placeAnOrder(String orderNo) {
		try {
			return new Result<PlaceOrder>(couponOrderService
					.placeAnOrder(orderNo));
		} catch (Exception e) {
			e.printStackTrace();
            throw new WebException(e.getMessage(), e);
		}
	}

	@ApiOperation("卡券订单退款申请")
    @ApiImplicitParams({
		@ApiImplicitParam(name="orderNo",value="订单号",dataType="String",paramType="query")
	})
    @PostMapping("/refund")
	public Result<?> refund(String orderNo) {
		try {
			couponOrderService.submitRefund(orderNo);
			return new Result<>();
		} catch (Exception e) {
			e.printStackTrace();
            throw new WebException(e.getMessage(), e);
		}
	}

	@ApiOperation("卡券订单支付结果通知")
    @PostMapping("/result")
	public Map<String, Object> result(@RequestBody JSONObject param) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			log.info("卡券订单支付结果通知报文："+JSONObject.toJSONString(param));
			
			//验签
			String sign = param.getString("sign");
			String appKey = FPayConfig.getAppKey();
			String appSecret = FPayConfig.getAppSecret();
			param.remove("sign");
			if (PDSignUtil.checkSign(param, sign, appKey, appSecret)) {
				log.info("验签成功：[sign="+sign+"][appKey="
						+appKey+"][appSecret="+appSecret+"]");
				couponOrderService.result(param);
				result.put("code", "0");
				result.put("message", "成功");
			} else {
				log.info("验签失败，请检查配置的appKey和appSecret：[sign="+sign
						+"][appKey="+appKey+"][appSecret="+appSecret+"]");
				result.put("code", "999");
				result.put("message", "验签失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.put("code", "999");
			result.put("message", "回调出错："+e.getMessage());
		}
		return result;
	}

	@ApiOperation("核销异步通知，核销成功后才会通知")
    @PostMapping("/usedResult")
	public Map<String, Object> usedResult(@RequestBody JSONObject param) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			System.out.println("请求报文："+param.toJSONString());
			//验签
			String sign = param.getString("sign");
			String appKey = FPayConfig.getAppKey();
			String appSecret = FPayConfig.getAppSecret();
			param.remove("sign");
			if (PDSignUtil.checkSign(param, sign, appKey, appSecret)) {
				log.info("验签成功：[sign="+sign+"][appKey="
						+appKey+"][appSecret="+appSecret+"]");
				couponOrderService.used(param);
				result.put("code", "0");
				result.put("message", "成功");
			} else {
				log.info("验签失败，请检查配置的appKey和appSecret：[sign="+sign
						+"][appKey="+appKey+"][appSecret="+appSecret+"]");
				result.put("code", "999");
				result.put("message", "验签失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.put("code", "999");
			result.put("message", "回调出错："+e.getMessage());
		}
		return result;
	}

	@ApiOperation("处理退款审核")
    @ApiImplicitParams({
		@ApiImplicitParam(name="jwt",value="加密的参数值（订单号&审核状态“1同意退款 2拒绝退款”）",dataType="String",paramType="query")
	})
	@PostMapping("/handleRefund")
	public Result<?> handleRefund(String jwt){
		Result<?> result = new Result<>();
		try {
			String data = jwtUtils.verifyToken(jwt);
			String[] d = data.split("&");
			String orderNo = d[0];
			String state = d[1];//1同意退款 2拒绝退款
			log.info("data="+data+",orderNo="+orderNo+",state="+state);
			couponOrderService.verifyRefund(orderNo, state);
			result.setSuccess(true);
			result.setMsg("成功");
			return result;
		} catch (Exception e) {
			e.printStackTrace();
            throw new WebException(e.getMessage(), e);
		}
	}

	@SuppressWarnings("unchecked")
	@ApiOperation("获取对账单下载的URL")
    @ApiImplicitParams({
		@ApiImplicitParam(name="jwt",value="加密的参数值（会计日期：格式为yyyy-MM-dd）",dataType="String",paramType="query")
	})
	@PostMapping("/billDownloadUrl")
	public Result<Map<String, Object>> billDownloadUrl(String jwt){
		Result<Map<String, Object>> result = new Result<Map<String, Object>>();
		try {
			String data = jwtUtils.verifyToken(jwt);
			Map<String, Object> resultData = FPayApi.billDownloadUrl(data);
			if (!"0".equals(resultData.get("code"))) {
				result.setSuccess(false);
				result.setMsg((String) resultData.get("message"));
				return result;
			}
			result.setSuccess(true);
			result.setMsg("成功");
			result.setData((Map<String, Object>) resultData.get("data"));
			return result;
		} catch (Exception e) {
			e.printStackTrace();
            throw new WebException(e.getMessage(), e);
		}
	}
}
